<script lang="ts" setup>
import type { FormInstance, FormProps, TableColumnType } from 'ant-design-vue';

import type { UnwrapRef } from 'vue';

import type { InfraCodegenApi } from '#/api/infra/codegen';

import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';

import { message } from 'ant-design-vue';

import { createCodegenList, getSchemaTableList } from '#/api/infra/codegen';
import { getDataSourceConfigList } from '#/api/infra/data-source-config';
import { $t } from '#/locales';

/** 定义组件事件 */
const emit = defineEmits<{
  (e: 'success'): void;
}>();

const formData = reactive<InfraCodegenApi.CodegenCreateListReq>({
  dataSourceConfigId: 0,
  tableNames: [], // 已选择的表列表
});

// 选中的表格行
const selectedRowKeys = ref<string[]>([]);
const selectedRows = ref<InfraCodegenApi.DatabaseTable[]>([]);

/** 模态框实例 */
const [Modal, modalApi] = useVbenModal({
  title: '导入表',
  class: 'w-3/4',
  async onConfirm() {
    modalApi.lock();
    // 1.1 获取表单值
    if (formData?.dataSourceConfigId === undefined) {
      message.error('请选择数据源');
      return;
    }
    // 1.2 校验是否选择了表
    if (formData.tableNames.length === 0) {
      message.error('请选择需要导入的表');
      return;
    }

    // 2. 提交请求
    const hideLoading = message.loading({
      content: '导入中...',
      key: 'action_key_msg',
    });
    try {
      await createCodegenList(formData);
      // 关闭并提示
      await modalApi.close();
      emit('success');
      message.success({
        content: $t('ui.actionMessage.operationSuccess'),
        key: 'action_key_msg',
      });
    } finally {
      hideLoading();
      modalApi.unlock();
    }
  },
  onCancel() {
    // 模态框关闭时清理拖拽状态
    draggedIndex.value = null;
    draggedOverIndex.value = null;
  },
});

interface FormState {
  dataSourceConfigId: string;
  name: string;
}
interface PageState {
  current: number;
  pageSize: number;
  total: number;
}
const formRef = ref<FormInstance>();
const formState: UnwrapRef<FormState> = reactive({
  dataSourceConfigId: '',
  name: '',
});
const options = ref<{ label: string; value: string }[]>([]);
const columns = ref<TableColumnType<InfraCodegenApi.DatabaseTable>[]>([
  {
    title: '表名称',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '表注释',
    dataIndex: 'comment',
    key: 'comment',
  },
]);

// 行选择配置
const rowSelection = {
  selectedRowKeys,
  onChange: (
    selectedKeys: string[],
    selectedRecords: InfraCodegenApi.DatabaseTable[],
  ) => {
    selectedRowKeys.value = selectedKeys;
    selectedRows.value = selectedRecords;
    formData.tableNames = selectedRecords.map((item) => item.name);
  },
};
const list = ref<InfraCodegenApi.DatabaseTable[]>([]);
const pageState = ref<PageState>({
  current: 1,
  pageSize: 10,
  total: 0,
});

// 拖拽排序相关
const tableRef = ref<HTMLElement | null>(null);
const draggedIndex = ref<null | number>(null);
const draggedOverIndex = ref<null | number>(null);
const handleFinish: FormProps['onFinish'] = (values) => {
  if (values.dataSourceConfigId === undefined) {
    return [];
  }
  formData.dataSourceConfigId = values.dataSourceConfigId;
  getSchemaTableList({
    pageNo: pageState.value.current,
    pageSize: pageState.value.pageSize,
    ...values,
  }).then((res) => {
    list.value = res;
    pageState.value.total = res.length;
    // 清空之前的选择状态
    selectedRowKeys.value = [];
    selectedRows.value = [];
    formData.tableNames = [];
    // 数据加载完成后初始化拖拽排序
    initSortable();
  });
};
const rules = {
  dataSourceConfigId: [{ required: true, message: '请选择数据源' }],
};
const handlePageChange = (current: number) => {
  pageState.value.current = current;
  handleFinish(formState);
  // 分页后重新初始化拖拽排序
  reinitSortable();
};

// 初始化拖拽排序
const initSortable = () => {
  nextTick(() => {
    if (!tableRef.value) {
      return;
    }

    try {
      // 获取表格组件的 DOM 元素
      const tableElement = (tableRef.value as any).$el;
      if (!tableElement) {
        return;
      }

      const tbody = tableElement.querySelector('.ant-table-tbody');
      if (!tbody) {
        return;
      }

      // 为每一行添加拖拽事件
      const rows = tbody.querySelectorAll('tr');
      rows.forEach((row: Element, index: number) => {
        (row as HTMLElement).draggable = true;
        (row as HTMLElement).style.cursor = 'move';

        // 拖拽开始
        row.addEventListener('dragstart', (e: Event) => {
          const dragEvent = e as DragEvent;
          draggedIndex.value = index;
          (row as HTMLElement).style.opacity = '0.5';
          dragEvent.dataTransfer!.effectAllowed = 'move';
        });

        // 拖拽结束
        row.addEventListener('dragend', () => {
          (row as HTMLElement).style.opacity = '';
          draggedIndex.value = null;
          draggedOverIndex.value = null;
        });

        // 拖拽进入
        row.addEventListener('dragover', (e: Event) => {
          const dragEvent = e as DragEvent;
          dragEvent.preventDefault();
          dragEvent.dataTransfer!.dropEffect = 'move';
          draggedOverIndex.value = index;
        });

        // 拖拽离开
        row.addEventListener('dragleave', () => {
          draggedOverIndex.value = null;
        });

        // 放置
        row.addEventListener('drop', (e: Event) => {
          const dragEvent = e as DragEvent;
          dragEvent.preventDefault();
          if (draggedIndex.value !== null && draggedIndex.value !== index) {
            // 更新数据顺序
            const movedItem = list.value.splice(draggedIndex.value, 1)[0];
            if (movedItem) {
              list.value.splice(index, 0, movedItem);
            }

            // 更新选中的表名顺序和选择状态
            if (selectedRowKeys.value.length > 0) {
              const selectedItems = list.value.filter((item) =>
                selectedRowKeys.value.includes(item.name),
              );
              formData.tableNames = selectedItems.map((item) => item.name);
              selectedRows.value = selectedItems;
            }
          }
        });
      });
    } catch (error) {
      console.warn('初始化拖拽排序失败:', error);
    }
  });
};

// 重新初始化拖拽排序（当数据变化时）
const reinitSortable = () => {
  // 延迟初始化，确保 DOM 更新完成
  setTimeout(() => {
    initSortable();
  }, 200);
};
onMounted(() => {
  getDataSourceConfigList().then((res) => {
    options.value = res.map((item) => ({
      label: item.name,
      value: item.id?.toString() ?? '',
    }));
    if (options.value.length > 0) {
      formState.dataSourceConfigId = options.value[0]?.value ?? '0';
      handleFinish(formState);
    }
  });
});
// 组件卸载时清理
onUnmounted(() => {
  // 清理拖拽事件监听器
  if (tableRef.value) {
    const tableElement = (tableRef.value as any).$el;
    if (tableElement) {
      const tbody = tableElement.querySelector('.ant-table-tbody');
      if (tbody) {
        const rows = tbody.querySelectorAll('tr');
        rows.forEach((row: Element) => {
          (row as HTMLElement).draggable = false;
          (row as HTMLElement).style.cursor = '';
          (row as HTMLElement).style.opacity = '';
        });
      }
    }
  }
});
</script>

<template>
  <Modal>
    <a-form
      ref="formRef"
      name="advanced_search"
      class="ant-advanced-search-form"
      :model="formState"
      :rules="rules"
      @finish="handleFinish"
    >
      <a-row :gutter="24">
        <a-col :span="12">
          <a-form-item name="dataSourceConfigId" label="数据源">
            <a-select
              v-model:value="formState.dataSourceConfigId"
              :options="options"
            />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item name="name" label="表名称">
            <a-input
              v-model:value="formState.name"
              placeholder="请输入表名称"
              allow-clear
            />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row>
        <a-col :span="24" style="text-align: right">
          <a-button type="primary" html-type="submit">Search</a-button>
          <a-button style="margin: 0 8px" @click="() => formRef?.resetFields()">
            Clear
          </a-button>
        </a-col>
      </a-row>
    </a-form>
    <a-table
      ref="tableRef"
      :columns="columns"
      :data-source="list"
      :row-key="(record: InfraCodegenApi.DatabaseTable) => record.name"
      :row-selection="rowSelection"
      row-selection-mode="multiple"
      :pagination="{
        current: pageState.current,
        pageSize: pageState.pageSize,
        total: pageState.total,
        onChange: handlePageChange,
      }"
    />
  </Modal>
</template>

<style scoped>
/* 拖拽排序样式 */
.sortable-ghost {
  opacity: 0.4;
  background: #f0f0f0;
}

.sortable-chosen {
  background: #e6f7ff;
  border: 1px dashed #1890ff;
}

.sortable-drag {
  background: #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transform: rotate(2deg);
}

/* 表格行拖拽时的样式 */
:deep(.ant-table-tbody > tr) {
  cursor: move;
  transition: all 0.3s ease;
}

:deep(.ant-table-tbody > tr:hover) {
  background-color: #f5f5f5;
}

/* 拖拽时的行样式 */
:deep(.sortable-ghost .ant-table-tbody > tr) {
  opacity: 0.4;
}

:deep(.sortable-chosen .ant-table-tbody > tr) {
  background-color: #e6f7ff;
  border: 1px dashed #1890ff;
}
</style>
